package engine;

import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

/**
 * 
 * A basic structure for all objects that participate in the physics engine.
 * 
 * @author Dylan Swiggett
 *
 */
public abstract class PhysicsObject {
	Vector centroid;	//The centroid of the object, and the origin of the local coordinate system
	Vector velocity;
	double w, r;		//The angular momentum and position of the object
	double m;			//The mass of the object
	
	/**
	 * 
	 * Return the bounding box for the shape, when rotated at the specified angle.
	 * 
	 * @return Bounding rectangle
	 */
	public abstract Rectangle2D getBoundingBox();
	
	/**
	 * 
	 * Get the list of all points to check for collision, e.g. all the points
	 * that form a polygon, or a set of bounding points on a circle.
	 * These points should all be in world coordinates.
	 * 
	 * @return
	 */
	public abstract ArrayList<Vector> getCollisionPoints();
	
	/**
	 * 
	 * If the point is within the Physics Object, return the shortest
	 * path for the point to exit the object. Otherwise, return null.
	 * 
	 * @param p
	 * @return Shortest exit path
	 */
	public abstract Vector pointInObject(Vector p);
	
	/**
	 * 
	 * Respond to the force moving in the specified direction, with the given force, at the specified position (Origin is the centroid).
	 * Return the response vector to the point force.
	 * 
	 * @param p
	 * @return
	 */
	public abstract Vector respondToForce(Vector velocity, Vector position, double m);
	
	/**
	 * 
	 * Simulate the collision of this object with the specified object. First check that a collision
	 * is actually happening, than apply the forces (both original and response). This method should
	 * be called both ways if two objects both respond to a particular reaction.
	 * 
	 * @param object
	 */
	public void collideWithPhysicsObject(PhysicsObject object){
		for (Vector p : object.getCollisionPoints()){
			/*
			 * Check if a collision is occurring at the point.
			 * In the final version, this will be done with an integrator.
			 */
			Vector collisionDirection = pointInObject(p);
			if (collisionDirection != null){
				Vector relativePoint = p.subtract(object.centroid);	//Point relative to the shape
				Vector connectionVector = relativePoint.normalize();	//Normalized vector to the centroid
				Vector rotationVelocity = new Vector(-connectionVector.getY(),connectionVector.getX()).
						scale(relativePoint.length() * object.w);	//Rotational vector of the point
				Vector velocity = object.velocity.add(rotationVelocity);
				object.respondToForce(velocity, p, m);
				respondToForce(velocity.scale(-1), p, m);
				System.out.println("Collision");
			}
		}
	}
}



